Switch TLS certificates to APP mode and share via peer relation#461
Draft
Switch TLS certificates to APP mode and share via peer relation#461
Conversation
- Changed TLSCertificatesRequiresV4 mode from Mode.UNIT to Mode.APP - Added certificate sharing via haproxy-peer relation app databag - Leader unit shares certificate data (cert, chain, private key) to peers - Non-leader units read certificate data from peer relation - Added _get_tls_information() helper for leader/non-leader branching - Added _reconcile_certificates() to handle sharing after writing to disk - Hooked peer relation-changed event to reconcile loop - Updated test fixtures for APP mode (local_app_data for CSR data, leader=True) Agent-Logs-Url: https://github.com/canonical/haproxy-operator/sessions/984ade73-92cb-4e20-89e1-2f2c22483668 Co-authored-by: Thanhphan1147 <42444001+Thanhphan1147@users.noreply.github.com>
- Test leader shares certificates to peer relation app databag - Test non-leader reads certificates from peer relation - Test non-leader without peer data skips TLS gracefully - Test non-leader haproxy-route reads from peer relation - Test share_certificates_via_peer_relation method directly - Test get_tls_information_from_peer_relation with data - Test get_tls_information_from_peer_relation without data returns None Agent-Logs-Url: https://github.com/canonical/haproxy-operator/sessions/984ade73-92cb-4e20-89e1-2f2c22483668 Co-authored-by: Thanhphan1147 <42444001+Thanhphan1147@users.noreply.github.com>
- Fix ruff RUF059: prefix unused variable with underscore - Fix ruff RUF015: use next() instead of list comprehension slice - Fix mypy union-attr: add assertions for optional relation types - Improve type annotation: use Application instead of typing.Any Agent-Logs-Url: https://github.com/canonical/haproxy-operator/sessions/984ade73-92cb-4e20-89e1-2f2c22483668 Co-authored-by: Thanhphan1147 <42444001+Thanhphan1147@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Enhance certificate sharing for HA deployment
Switch TLS certificates to APP mode and share via peer relation
Apr 13, 2026
| self.haproxy_service.reconcile_default(charm_state) | ||
| self.unit.status = ops.ActiveStatus() | ||
|
|
||
| def _get_tls_information( |
Collaborator
There was a problem hiding this comment.
@copilot This logic needs to be moved to the from_charm method of the TLSInformation dataclass.
Contributor
Author
There was a problem hiding this comment.
Moved the leader/non-leader branching logic into TLSInformation.from_charm() in state/tls.py. The method now returns Optional[TLSInformation] — leader path reads from the TLS library, non-leader path reads from the peer relation via _from_peer_relation(). Removed _get_tls_information() from charm.py and get_tls_information_from_peer_relation() from TLSRelationService. Also moved PEER_TLS_KEY constant to state/tls.py. See commit a3d6e5a.
…harm - Moved _get_tls_information() logic from charm.py into TLSInformation.from_charm() in state/tls.py per reviewer feedback - from_charm() now returns Optional[TLSInformation]: leader reads from TLS library, non-leader reads from peer relation via new _from_peer_relation() classmethod - Removed _get_tls_information() method from charm.py - Moved PEER_TLS_KEY constant to state/tls.py (canonical location for TLS state) - Removed get_tls_information_from_peer_relation() from TLSRelationService (logic now in TLSInformation._from_peer_relation) - Updated tests to test through TLSInformation.from_charm() Agent-Logs-Url: https://github.com/canonical/haproxy-operator/sessions/96fecf67-9c28-47d1-8590-78ac4718d7c2 Co-authored-by: Thanhphan1147 <42444001+Thanhphan1147@users.noreply.github.com>
Agent-Logs-Url: https://github.com/canonical/haproxy-operator/sessions/96fecf67-9c28-47d1-8590-78ac4718d7c2 Co-authored-by: Thanhphan1147 <42444001+Thanhphan1147@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In HA deployments, each unit was requesting its own TLS certificate (UNIT mode), hitting Let's Encrypt's rate limit of 5 certs per domain per 168h. Switch to APP mode so a single certificate is requested per application, with the leader sharing it to peers.
Core changes
src/state/tls.py:TLSInformation.from_charm()now returnsOptional[TLSInformation]and handles both leader and non-leader paths — leader reads from TLS library, non-leader reads from peer relation via_from_peer_relation().PEER_TLS_KEYconstant is defined here as the canonical location for TLS state.src/charm.py: SwitchTLSCertificatesRequiresV4fromMode.UNITtoMode.APP. All callers useTLSInformation.from_charm()directly for leader/non-leader branching. Add_reconcile_certificates()which writes certs to disk and, if leader, shares to peer relation app databag. Observehaproxy-peersrelation-changedto trigger reconcile on non-leader units when cert data arrives.src/tls_relation.py: Addshare_certificates_via_peer_relation()to serialize cert+chain+key into peer relation app databag. Remove thecertificate_requestsguard fromcertificate_available()since non-leader units receive certs from peers, not the TLS library.Data flow
Test changes
certificates_integrationfixture to uselocal_app_data(APP mode stores CSRs in app databag, not unit databag)leader=Truefrom_charm(), non-leader with haproxy-route mode, round-trip serialization ofTLSInformation, empty peer data returnsNone